package com.producteev4j.services.version0;

import com.producteev4j.exceptions.ProducteevException;
import com.producteev4j.model.json.activity.ActivityImpl;
import com.producteev4j.model.json.activity.ActivityListResponseWrapperImpl;
import com.producteev4j.model.json.task.*;
import com.producteev4j.model.json.user.UserListWrapperImpl;
import com.producteev4j.model.request.ProducteevGetRequest;
import com.producteev4j.model.request.ProducteevRequest;
import com.producteev4j.model.response.*;
import com.producteev4j.transport.ProducteevTransport;

import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: jcarrey
 * Date: 18/05/11
 * Time: 12:25
 * To change this template use File | Settings | File Templates.
 */
public class ProducteevTaskServiceV0Impl implements ProducteevTaskService {

    // private static final Logger logger = Logger.getLogger(ProducteevServiceV0.class);

    private static final String TASK_CONTEXT_PATH = "/tasks";

    private static final String TASK_CREATE_SERVICE = "/create.json";
    private static final String TASK_SHOW_LIST_SERVICE = "/show_list.json";
    private static final String TASK_VIEW_SERVICE = "/view.json";
    private static final String TASK_MY_TASKS_SERVICE = "/my_tasks.json";
    private static final String TASK_MY_TEAM_TASKS_SERVICE = "/my_team_tasks.json";
    private static final String TASK_ARCHIVED_SERVICE = "/archived.json";
    private static final String TASK_SET_TITLE_SERVICE = "/set_title.json";
    private static final String TASK_SET_STAR_SERVICE = "/set_star.json";
    private static final String TASK_SET_RESPONSIBLE_SERVICE = "/set_responsible.json";
    private static final String TASK_UNSET_RESPONSIBLE_SERVICE = "/unset_responsible.json";
    private static final String TASK_SET_DEADLINE_SERVICE = "/set_deadline.json";
    private static final String TASK_UNSET_DEADLINE_SERVICE = "/unset_deadline.json";
    private static final String TASK_SET_REMINDER_SERVICE = "/set_reminder.json";
    private static final String TASK_SET_REPEATING_SERVICE = "/set_repeating.json";
    private static final String TASK_UNSET_REPEATING_SERVICE = "/unset_repeating.json";
    private static final String TASK_DELETE_SERVICE = "/delete.json";
    private static final String TASK_ACCESS_SERVICE = "/access.json";
    private static final String TASK_LABELS_SERVICE = "/labels.json";
    private static final String TASK_CHANGE_LABELS_SERVICE = "/change_labels.json";
    private static final String TASK_SET_WORKSPACE_SERVICE = "/set_workspace.json";
    private static final String TASK_PRIVACY_SERVICE = "/privacy.json";
    private static final String TASK_NOTE_VIEW_SERVICE = "/note_view.json";
    private static final String TASK_NOTES_GET_SERVICE = "/notes_get.json";
    private static final String TASK_NOTE_CREATE_SERVICE = "/note_create.json";
    private static final String TASK_DELETE_NOTE_SERVICE = "/note_delete.json";
    private static final String TASK_ACTIVITY_VIEW_SERVICE = "/activity_view.json";
    private static final String TASK_ACTIVITIES_GET_SERVICE = "/activities_get.json";
    private static final String TASK_SET_STATUS_SERVICE = "/set_status.json";

    private static final String TASK_CREATE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_CREATE_SERVICE;
    private static final String TASK_SHOW_LIST_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SHOW_LIST_SERVICE;
    private static final String TASK_VIEW_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_VIEW_SERVICE;
    private static final String TASK_MY_TASKS_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_MY_TASKS_SERVICE;
    private static final String TASK_MY_TEAM_TASKS_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_MY_TEAM_TASKS_SERVICE;
    private static final String TASK_SET_STATUS_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_STATUS_SERVICE;
    private static final String TASK_ARCHIVED_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_ARCHIVED_SERVICE;
    private static final String TASK_SET_TITLE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_TITLE_SERVICE;
    private static final String TASK_SET_STAR_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_STAR_SERVICE;
    private static final String TASK_SET_RESPONSIBLE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_RESPONSIBLE_SERVICE;
    private static final String TASK_UNSET_RESPONSIBLE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_UNSET_RESPONSIBLE_SERVICE;
    private static final String TASK_SET_DEADLINE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_DEADLINE_SERVICE;
    private static final String TASK_UNSET_DEADLINE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_UNSET_DEADLINE_SERVICE;
    private static final String TASK_SET_REMINDER_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_REMINDER_SERVICE;
    private static final String TASK_SET_REPEATING_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_REPEATING_SERVICE;
    private static final String TASK_UNSET_REPEATING_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_UNSET_REPEATING_SERVICE;
    private static final String TASK_DELETE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_DELETE_SERVICE;
    private static final String TASK_ACCESS_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_ACCESS_SERVICE;
    private static final String TASK_LABELS_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_LABELS_SERVICE;
    private static final String TASK_CHANGE_LABELS_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_CHANGE_LABELS_SERVICE;
    private static final String TASK_SET_WORKSPACE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_SET_WORKSPACE_SERVICE;
    private static final String TASK_PRIVACY_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_PRIVACY_SERVICE;
    private static final String TASK_NOTE_VIEW_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_NOTE_VIEW_SERVICE;
    private static final String TASK_NOTES_GET_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_NOTES_GET_SERVICE;
    private static final String TASK_NOTE_CREATE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_NOTE_CREATE_SERVICE;
    private static final String TASK_DELETE_NOTE_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_DELETE_NOTE_SERVICE;
    private static final String TASK_ACTIVITY_VIEW_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_ACTIVITY_VIEW_SERVICE;
    private static final String TASK_ACTIVITIES_GET_ENDPOINT = ProducteevServiceV0.PRODUCTEEV_API_ENDPOINT + TASK_CONTEXT_PATH + TASK_ACTIVITIES_GET_SERVICE;


    private static String TITLE_PARAM = "title";
    private static String ID_RESPONSIBLE_PARAM = "id_responsible";
    private static String ID_DASHBOARD_PARAM = "id_dashboard";
    private static String DEADLINE_PARAM = "deadline";
    private static String ALL_DAY_PARAM = "all_day";
    private static String REMINDER_PARAM = "reminder";
    private static String STATUS_PARAM = "status";
    private static String STARS_PARAM = "star";
    private static String REPEATING_INTERVAL_PARAM = "repeating_interval";
    private static String REPEATING_VALUE_PARAM = "repeating_value";
    private static String ID_LABEL_PARAM = "id_label";
    private static String TASK_ID_PARAM = "id_task";
    private static String PAGE_PARAM = "page";
    private static String TASK_STATUS_PARAM = "status";
    private static String TASK_STARS_PARAM = "star";
    private static final String SINCE_PARAM = "since";
    private static final String TASK_RESPONSIBLE_PARAM = "id_responsible";
    private static final String TASK_DEADLINE_PARAM = "deadline";
    private static final String TASK_ALLDAY_PARAM = "all_day";
    private static final String TASK_REMINDER_PARAM = "reminder";
    private static final String TASK_REPEATING_INTERVAL_PARAM = "repeating_interval";
    private static final String TASK_REPEATING_VALUE_PARAM = "repeating_value";
    private static final String TASK_TITLE_PARAM = "title";
    private static final String TRUE_VALUE = "1";
    private static final String FALSE_VALUE = "0";
    private static final String NOTE_MESSAGE_PARAM = "message";
    private static final String ID_NOTE_PARAM = "id_note";
    private static final String TASK_ID_ACTIVITY_PARAM = "id_activity";


    /**
     * 100 activities/page
     *
     * @param transport
     * @param userToken
     * @param idTask
     * @param page      - statrts at 1
     * @throws ProducteevException
     */
    public List<? extends ActivityWrapper> getTaskActivity(ProducteevTransport transport, String userToken, long idTask, Integer page) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_ACTIVITIES_GET_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        if (page != null) {
            request.getParams().putValue(PAGE_PARAM, page);
        }
        request.setResponseClass(ActivityListResponseWrapperImpl.class);
        return ProducteevValidator.assertNoError(((ActivityListResponseWrapperImpl) transport.process(request, userToken))).getTaskActivities();
    }

    // TODO 404 - Not found
    public Activity getActivity(ProducteevTransport transport, String userToken, long idActivity) throws ProducteevException {
        ActivityImpl activity = new ActivityImpl();
        activity.setError(new ProducteevErrorImpl());
        activity.getError().setMessage("Service not available yet");
        activity.getError().setRequest(TASK_ACTIVITY_VIEW_ENDPOINT);
        return activity;
        /*
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_ACTIVITY_VIEW_ENDPOINT);
        request.getParams().putValue(TASK_ID_ACTIVITY_PARAM, idActivity);

        request.setResponseClass(ActivityWrapperImpl.class);
         return ((ActivityWrapperImpl) transport.process(request, userToken)).getActivity();
         */
    }

    public boolean deleteNote(ProducteevTransport transport, String userToken, long idNote) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_DELETE_NOTE_ENDPOINT);
        request.getParams().putValue(ID_NOTE_PARAM, idNote);
        request.setResponseClass(BaseResponse.class);
        return !(ProducteevValidator.assertNoError((BaseResponse) transport.process(request, userToken))).isError();
    }

    public Note createNote(ProducteevTransport transport, String userToken, long idTask, String message) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_NOTE_CREATE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(NOTE_MESSAGE_PARAM, message);
        request.setResponseClass(NoteWrapperImpl.class);
        return (ProducteevValidator.assertNoError((NoteWrapperImpl) transport.process(request, userToken))).getNote();
    }

    public List<? extends NoteWrapper> getTaskNotes(ProducteevTransport transport, String userToken, long idTask, Date since) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_NOTES_GET_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(SINCE_PARAM, since);
        request.setResponseClass(NoteListResponseWrapperImpl.class);
        return (ProducteevValidator.assertNoError((NoteListResponseWrapperImpl) transport.process(request, userToken))).getNotes();
    }

    public Note getNote(ProducteevTransport transport, String userToken, long idNote) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_NOTE_VIEW_ENDPOINT);
        request.getParams().putValue(ID_NOTE_PARAM, idNote);
        request.setResponseClass(NoteWrapperImpl.class);
        return (ProducteevValidator.assertNoError((NoteWrapperImpl) transport.process(request, userToken))).getNote();
    }

    /*
    public List<? extends UserWrapper> getTaskUserList(ProducteevTransport transport, String userToken, long idTask) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_PRIVACY_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.setResponseClass(UserListWrapperImpl.class);
        return ((UserListWrapperImpl) transport.process(request, userToken)).getUsers();
    }
    */
    public Task setTaskWorkspace(ProducteevTransport transport, String userToken, long idTask, long idDashboard) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_WORKSPACE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(ID_DASHBOARD_PARAM, idDashboard);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    public Task changeTaskLabels(ProducteevTransport transport, String userToken, long idTask, Long[] idLabels) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_CHANGE_LABELS_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        if (idLabels != null) {
            request.getParams().putMultivalues(ID_LABEL_PARAM, idLabels);
        }
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    public List<? extends LabelWrapper> getTaskLabels(ProducteevTransport transport, String userToken, long idTask) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_LABELS_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.setResponseClass(LabelListResponseWrapperImpl.class);
        return (ProducteevValidator.assertNoError((LabelListResponseWrapperImpl) transport.process(request, userToken))).getLabels();
    }

    public List<? extends UserWrapper> getTaskAccessControlList(ProducteevTransport transport, String userToken, long idTask) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_ACCESS_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.setResponseClass(UserListWrapperImpl.class);
        return (ProducteevValidator.assertNoError((UserListWrapperImpl) transport.process(request, userToken))).getAccesslist();
    }

    public boolean deleteTask(ProducteevTransport transport, String userToken, long idTask) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_DELETE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.setResponseClass(BaseResponse.class);
        return !(ProducteevValidator.assertNoError((BaseResponse) transport.process(request, userToken))).isError();
    }

    /**
     * unset the deadline
     *
     * @param transport
     * @param userToken
     * @param idTask
     * @return
     * @throws ProducteevException
     */
    public Task unsetTaskRepeating(ProducteevTransport transport, String userToken, long idTask) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_UNSET_REPEATING_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }


    /**
     * @param transport
     * @param userToken
     * @param idTask
     * @param repeatingInterval - day(s), weekday(s), week(s), month(s) and year(s)
     * @param repeatingValue    - (Optional) Number of days
     * @return
     * @throws ProducteevException
     */
    public Task setTaskRepeating(ProducteevTransport transport, String userToken, long idTask, String repeatingInterval, Integer repeatingValue) throws ProducteevException {

        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_REPEATING_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_REPEATING_INTERVAL_PARAM, repeatingInterval);
        if (repeatingValue != null) {
            request.getParams().putValue(TASK_REPEATING_VALUE_PARAM, repeatingValue);
        }

        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    /**
     * @param transport
     * @param userToken
     * @param idTask
     * @param idReminder - (0 = "None", 1 = "5 minutes before", 2 = "15 minutes before", 3 = "30 minutes before", 4 = "1 hour before", 5 = "2 hours before", 6 = "1 day before", 7 = "2 days before", 8 = "on date of event")
     * @return
     * @throws ProducteevException
     */
    public Task setTaskReminder(ProducteevTransport transport, String userToken, long idTask, int idReminder) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_REMINDER_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_REMINDER_PARAM, idReminder);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    /**
     * unset the deadline
     *
     * @param transport
     * @param userToken
     * @param idTask
     * @return
     * @throws ProducteevException
     */
    public Task unsetTaskDeadline(ProducteevTransport transport, String userToken, long idTask) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_UNSET_DEADLINE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }


    /**
     * @param transport
     * @param userToken
     * @param idTask
     * @param deadline
     * @param allDay    =1 -> deadline ignored, =0 -> the deadline
     * @return
     */
    public Task setTaskDeadline(ProducteevTransport transport, String userToken, long idTask, Date deadline, boolean allDay) throws ProducteevException {

        if (!allDay && deadline == null) {
            throw new IllegalArgumentException("Deadline should not be null, or allDay = true");
        }
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_DEADLINE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_ALLDAY_PARAM, allDay ? TRUE_VALUE : FALSE_VALUE);
        request.getParams().putValue(TASK_DEADLINE_PARAM, deadline);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    /**
     * @param transport
     * @param userToken
     * @param idTask
     * @param idResponsible - Number of stars from 0 to 5
     * @return
     * @throws ProducteevException
     */
    public Task unsetTaskResponsible(ProducteevTransport transport, String userToken, long idTask, long idResponsible) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_UNSET_RESPONSIBLE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_RESPONSIBLE_PARAM, idResponsible);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    /**
     * @param transport
     * @param userToken
     * @param idTask
     * @param idResponsible - Number of stars from 0 to 5
     * @return
     * @throws ProducteevException
     */
    public Task setTaskResponsible(ProducteevTransport transport, String userToken, long idTask, long idResponsible) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_RESPONSIBLE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_RESPONSIBLE_PARAM, idResponsible);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }

    /**
     * @param transport
     * @param userToken
     * @param idTask
     * @param stars     - Number of stars from 0 to 5
     * @return
     * @throws ProducteevException
     */
    public Task setTaskStars(ProducteevTransport transport, String userToken, long idTask, int stars) throws ProducteevException {

        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_STAR_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_STARS_PARAM, stars);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();

    }


    /**
     * @param transport
     * @param userToken
     * @param status
     * @return
     * @throws ProducteevException
     */
    public Task setTaskStatus(ProducteevTransport transport, String userToken, long idTask, int status) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_STATUS_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_STATUS_PARAM, status);
        request.setResponseClass(TaskWrapperImpl.class);
        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }


    /**
     * @param transport
     * @param userToken
     * @param title
     * @return
     * @throws ProducteevException
     */
    public Task setTaskTitle(ProducteevTransport transport, String userToken, long idTask, String title) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SET_TITLE_ENDPOINT);
        request.getParams().putValue(TASK_ID_PARAM, idTask);
        request.getParams().putValue(TASK_TITLE_PARAM, title);
        request.setResponseClass(TaskWrapperImpl.class);
        return ProducteevValidator.assertNoError(((TaskWrapperImpl) transport.process(request, userToken))).getTask();
    }


    public List<? extends TaskWrapper> getMyTeamTasks(ProducteevTransport transport, String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_MY_TEAM_TASKS_ENDPOINT);
        request.setResponseClass(TaskListWrapperImpl.class);
        if (since != null) {
            request.getParams().putValue(SINCE_PARAM, since);
        }
        if (dashboard != null) {
            request.getParams().putValue(ID_DASHBOARD_PARAM, dashboard);
        }
        if (page != null) {
            request.getParams().putValue(PAGE_PARAM, page);
        }
        return ProducteevValidator.assertNoError(((TaskListWrapperImpl) transport.process(request, userToken))).getTasks();

    }

    public List<? extends TaskWrapper> getMyTasks(ProducteevTransport transport, String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_MY_TASKS_ENDPOINT);
        request.setResponseClass(TaskListWrapperImpl.class);
        if (since != null) {
            request.getParams().putValue(SINCE_PARAM, since);
        }
        if (dashboard != null) {
            request.getParams().putValue(ID_DASHBOARD_PARAM, dashboard);
        }
        if (page != null) {
            request.getParams().putValue(PAGE_PARAM, page);
        }
        return ProducteevValidator.assertNoError(((TaskListWrapperImpl) transport.process(request, userToken))).getTasks();

    }

    public List<? extends TaskWrapper> getArchivedTasks(ProducteevTransport transport, String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_ARCHIVED_ENDPOINT);
        request.setResponseClass(TaskListWrapperImpl.class);
        if (since != null) {
            request.getParams().putValue(SINCE_PARAM, since);
        }
        if (dashboard != null) {
            request.getParams().putValue(ID_DASHBOARD_PARAM, dashboard);
        }
        if (page != null) {
            request.getParams().putValue(PAGE_PARAM, page);
        }
        return (ProducteevValidator.assertNoError((TaskListWrapperImpl) transport.process(request, userToken))).getTasks();

    }


    /**
     * Returns 200 tasks
     *
     * @param transport
     * @param userToken
     * @param since
     * @param dashboard
     * @param page
     * @return
     * @throws ProducteevException
     */
    public List<? extends TaskWrapper> getTasks(ProducteevTransport transport, String userToken, Date since, Long dashboard, Integer page) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_SHOW_LIST_ENDPOINT);
        request.setResponseClass(TaskListWrapperImpl.class);
        if (since != null) {
            request.getParams().putValue(SINCE_PARAM, since);
        }
        if (dashboard != null) {
            request.getParams().putValue(ID_DASHBOARD_PARAM, dashboard);
        }
        if (page != null) {
            request.getParams().putValue(PAGE_PARAM, page);
        }
        return (ProducteevValidator.assertNoError((TaskListWrapperImpl) transport.process(request, userToken))).getTasks();

    }

    @Override
    public Task getTask(ProducteevTransport transport, String userToken, long taskId) throws ProducteevException {
        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_VIEW_ENDPOINT);
        request.setResponseClass(TaskWrapperImpl.class);
        request.getParams().putValue(TASK_ID_PARAM, taskId);

        return (ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken))).getTask();

    }

    public Task createTask(ProducteevTransport transport, String userToken, String title, Long idResponsible,
                           Long idDashboard, String deadline, Integer allDay, Integer reminder, Integer status,
                           Integer star, String repeatinginterval, Integer repeatingValue, Long[] idLabel) throws ProducteevException {

        ProducteevRequest request = new ProducteevGetRequest();
        request.setEndpoint(TASK_CREATE_ENDPOINT);
        request.setResponseClass(TaskWrapperImpl.class);

        if (title != null) {
            request.getParams().putValue(TITLE_PARAM, title);
        } else {
            throw new IllegalArgumentException("Title is mandatory");
        }

        if (idResponsible != null) {
            request.getParams().putValue(ID_RESPONSIBLE_PARAM, idResponsible);
        }
        if (idDashboard != null) {
            request.getParams().putValue(ID_DASHBOARD_PARAM, idDashboard);
        }
        if (deadline != null) {
            request.getParams().putValue(DEADLINE_PARAM, deadline);
        }
        if (allDay != null) {
            request.getParams().putValue(ALL_DAY_PARAM, allDay);
        }
        if (reminder != null) {
            request.getParams().putValue(REMINDER_PARAM, reminder);
        }
        if (status != null) {
            request.getParams().putValue(STATUS_PARAM, status);
        }
        if (star != null) {
            request.getParams().putValue(STARS_PARAM, star);
        }
        if (repeatinginterval != null) {
            request.getParams().putValue(REPEATING_INTERVAL_PARAM, repeatinginterval);
        }
        if (repeatingValue != null) {
            request.getParams().putValue(REPEATING_VALUE_PARAM, repeatingValue);
        }

        if (idLabel != null) {
            request.getParams().putMultivalues(ID_LABEL_PARAM, idLabel);
        }

        return ProducteevValidator.assertNoError((TaskWrapperImpl) transport.process(request, userToken)).getTask();

    }
}
